<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>promise配合async和await</title>
</head>

<body>
    <script>

        // 需求：异步操作A执行完后，再执行异步操作B，再执行异步操作C
        // 原来的写法
        /* setTimeout(() => {
            console.log('异步操作a执行完毕！');
            setTimeout(() => {
                console.log('异步操作b执行完毕！');
                setTimeout(() => {
                    console.log('异步操作c执行完毕！');
                }, 1000)
            }, 1000)
        }, 1000) */


        /* // promise的写法
        new Promise(resolve => {
            setTimeout(() => {
                console.log('异步操作a执行完毕');
                resolve([1, 2, 3])
            }, 1000)
        }).then(data => {
            return new Promise((resolve) => [
                setTimeout(() => {
                    console.log('异步操作b执行完毕');
                    resolve(data)
                }, 1000)
            ])
        }).then(data => {
            setTimeout(() => {
                console.log('异步操作c执行完毕');
            }, 1000)
        }) */

        // promise配合async和await的写法
        /* let promise1 = new Promise((resolve) => {
            setTimeout(() => {
                console.log('异步操作a执行完毕');
                resolve('成功')
            }, 1000)
        }
        )
        let promise2 = new Promise((resolve) => {
            setTimeout(() => {
                console.log('异步操作b执行完毕');
                resolve('成功')
            }, 1000)
        }
        )
        let promise3 = new Promise((resolve) => {
            setTimeout(() => {
                console.log('异步操作c执行完毕');
                resolve('成功')
            }, 1000)
        }
        )

        async function fn1() {
            await promise2
            await promise1
            await promise3
        }
        fn1() */

        // 注意：这是一个错误的写法，因为new Promise写在外面，promise1、promise2、promise3其实是同步执行代码
        // 也就是说，promise1执行异步操作可能还没有完，又立马去执行promise2，以此类推
        // 没有达到，等promise1执行完毕后再去promise2的效果，我们看到的效果相当于同步



        // 改进方案
        async function fn2() {
            await new Promise((resolve) => {
                setTimeout(() => {
                    console.log('异步操作a执行完毕');
                    resolve('成功')
                }, 1000)
            }
            )

            await new Promise((resolve) => {
                setTimeout(() => {
                    console.log('异步操作b执行完毕');
                    resolve('成功')
                }, 1000)
            }
            )

            await new Promise((resolve) => {
                setTimeout(() => {
                    console.log('异步操作c执行完毕');
                    resolve('成功')
                }, 1000)
            }
            )
        }

        // fn2()

        // 封装后的形式
        function p1() {
            return new Promise((resolve) => {
                setTimeout(() => {
                    console.log('异步操作a执行完毕');
                    resolve('成功1')
                }, 1000)
            }
            )
        }
        function p2() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log('异步操作b执行完毕');
                    // resolve('成功2')
                    reject('失败2')
                }, 1000)
            }
            )
        }
        function p3() {
            return new Promise((resolve) => {
                setTimeout(() => {
                    console.log('异步操作c执行完毕');
                    resolve('成功3')
                }, 1000)
            }
            )
        }

        async function fn3() {
            await p2()
            await p3()
            await p1()
        }

        // fn3()

        // try/catch 防止代码出错，程序终止
        async function fn4() {
            try {
                await p2()
                await p3()
                await p1()
            } catch (error) {
                console.log('失败：', error);
            } finally {
                console.log('最后执行的');
            }
        }
        fn4()

    </script>
</body>

</html>